import React, { useState, useEffect, FC } from 'react';
import { connect } from 'react-redux';
import { ConnectProps, ConnectState } from 'typings/connect';
import {
  IOrgTreeItem,
  IOrgTreeCheckedItem
} from './interface';
import { IResOrgTreeItem } from './interface';
import _ from 'lodash';
import { SUCCESS_CODE } from '@/services/constant';

interface FlattenTree {
  [index: string]: IOrgTreeCheckedItem;
}

// 展示的数据
interface IShowItem extends IOrgTreeCheckedItem {
  visible: boolean;
}

interface IOrgModalProps extends ConnectProps {
  expandKeys?: string[];
  title?: string;
  visible: boolean;
  onCancel: () => void;
  onSubmit: (
    checkedOrgs: string[],
    checkedOrgItems: IOrgTreeCheckedItem[],
  ) => void;
  onInit?: (
    checkedOrgs: string[],
    checkedOrgItems: IOrgTreeCheckedItem[],
  ) => void;
  treeLoading?: boolean;
  defaultCheckedOrgs?: string[]; // 用于treeData改变的时候，传给外面中文显示
}

const OrgToUserModal: FC<IOrgModalProps> = (props) => {
  const [inputInfo, setInputInfo] = useState<string>();
  const [filteredData, setFilteredData] = useState<IOrgTreeItem[]>([]);
  const [treeData, setTreeData] = useState<IOrgTreeItem[]>([]);
  const [flattenTree, setFlattenTree] = useState<FlattenTree>({});
  const [checkedOrgs, setOrgs] = useState<string[]>([]);
  const [checkedOrgItems, setOrgItems] = useState<IOrgTreeCheckedItem[]>([]);
  const [expandKeys, setExpKeys] = useState<string[]>([]);

  // 为了处理人员范围的反显，
  // 1.defaultCheckedOrgsItems 与 treeData 设置的顺序不一致
  // 2.初始化完成之后给个flag，避免死循环
  // 这里处理的不是很好，待优化
  // 如果defaultCheckedOrgs本来就是空的,则第一次设置值的时候会多走一次(不是期望的结果)
  const initOrgInfo = (
    defaultCheckedOrgs: string[],
    flattenObj: FlattenTree
  ) => {
    if (defaultCheckedOrgs) {
      defaultCheckedOrgs = defaultCheckedOrgs.filter((id) => {
        return !!flattenObj[id];
      });
      const defaultCheckedOrgsItems = defaultCheckedOrgs.map(
        (id) => flattenObj[id]
      );
      setOrgs(defaultCheckedOrgs);
      setOrgItems(defaultCheckedOrgsItems);
      props.onInit && props.onInit(defaultCheckedOrgs, defaultCheckedOrgsItems);
    }
  };

  // 1.对数据做一层过滤：遍历数组，如果item的parentId也在数组中，则不展示该节点，这时候做一下标志
  const filterItems = (ids: string[], items: IOrgTreeCheckedItem[]) => {
    const result: IShowItem[] = items.map((el) => {
      // if ( el.parentKey && ids.indexOf(el.parentKey) > -1) {
      //   return { ...el, ...{ visible: false } };
      // }
      return { ...el, ...{ visible: true } };
    });
    return result.filter(({ visible }) => visible);
  };

  const formatTreeData = (treeData: IResOrgTreeItem[], parentKey?: string) => {
    const result: IOrgTreeItem[] = [];
    let flattenObj: { [index: string]: IOrgTreeCheckedItem } = {};
    for (let i = 0; i < treeData.length; i++) {
      let formattedPersons: IOrgTreeItem[] = [];
      let children: IOrgTreeItem[] = [];
      const personFlattenObj: { [index: string]: IOrgTreeCheckedItem } = {};
      let childFlattenObj: { [index: string]: IOrgTreeCheckedItem } = {};

      if (treeData[i].persons) {
        formattedPersons = treeData[i].persons.map((el) => {
          const obj = {
            key: el.userId,
            title: el.name,
            type: el.type,
            parentKey: treeData[i].id
          };
          personFlattenObj[obj.key] = obj;
          return obj;
        });
      }
      if (treeData[i].children) {
        const tmp = formatTreeData(treeData[i].children || [], treeData[i].id);
        children = tmp.result;
        childFlattenObj = tmp.flattenObj;
        if (formattedPersons) {
          children = children
            ? children.concat(formattedPersons)
            : formattedPersons;

          childFlattenObj = { ...childFlattenObj, ...personFlattenObj };
        }
      }

      flattenObj = {
        [treeData[i].id]: {
          key: treeData[i].id,
          title: treeData[i].orgName,
          type: treeData[i].type,
          parentKey
        },
        ...flattenObj,
        ...childFlattenObj
      };
      result.push({
        key: treeData[i].id,
        title: treeData[i].orgName,
        type: treeData[i].type,
        children: children,
        parentId: parentKey
      });
    }
    return { result, flattenObj };
  };

  const treeSelect = (key: string[], checkedItems: IOrgTreeCheckedItem[]) => {
    setOrgs(key);

    setOrgItems(checkedItems);
  };

  const onSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
    const val = e.target.value;
    setInputInfo(val);
    const filteredData = filterData(treeData, val);
    setFilteredData(filteredData);
  };

  useEffect(() => {
    if (props.defaultCheckedOrgs && !_.isEmpty(flattenTree)) {
      initOrgInfo(props.defaultCheckedOrgs, flattenTree);
    }
  }, [props.defaultCheckedOrgs, flattenTree]);

  // https://www.robinwieruch.de/react-hooks-fetch-data
  useEffect(() => {
    let didCancel = false;
    const getTreeData = () => {
      const { dispatch } = props;
      dispatch &&
        dispatch({
          type: 'design/getOrgData'
        }).then((res?: any) => {
          if (res.status == SUCCESS_CODE) {
            if (didCancel) {
              return;
            }
            const treeData = formatTreeData([res.data]);
            const flattenObj = treeData.flattenObj;
            setFlattenTree(flattenObj);
            setTreeData(treeData.result);
            // setFilteredData(filterData(treeData.result, x));
            setFilteredData(filterData(treeData.result, ''));
          }
        });
    };
    getTreeData();

    return () => {
      didCancel = true;
    };
  }, []);

  useEffect(() => {
    setExpKeys(props.expandKeys || []);
  }, [props.expandKeys]);

  const filterData = (data: IOrgTreeItem[], keyword?: string) => {
    if (!keyword || !data) {
      return data;
    }
    const expands: string[] = [];
    const result = doFilter(JSON.parse(JSON.stringify(data)), keyword, expands);
    setExpKeys([...expands, ...expandKeys]);
    return result;
  };
  const doFilter = (
    arr: IOrgTreeItem[] | undefined,
    keyword: string,
    expands: string[]
  ) => {
    if (!arr) {
      return [];
    }
    for (let i = 0; i < arr.length; i++) {
      const children = doFilter(arr[i].children, keyword, expands);
      if (children && children.length > 0) {
        arr[i].children = children;
      } else {
        arr[i].children = [];
      }
    }
    return arr.filter((el) => {
      // 有children的情况下不用过滤
      if (el.children && el.children.length > 0) {
        expands.push(el.key);
        return true;
      }
      const includeKeyWord = el.title.indexOf(keyword) > -1;
      if (includeKeyWord) {
        expands.push(el.key);
      }
      return includeKeyWord;
    });
  };

  return <>placeholder</>;

  // return (
  //   <Modal
  //     centered
  //     width="640px"
  //     wrapClassName={classnames(styles.orgToUser, 'antModal')}
  //     title={props.title || '谁可以发起'}
  //     visible={props.visible}
  //     onCancel={() => toggleModal('close')}
  //     onOk={() => toggleModal('submit')}
  //   >
  //     <div className={styles.wrap}>
  //       <div className={styles.content}>
  //         <div className={styles.left}>
  //           <Search
  //             className={styles.searchInput}
  //             placeholder="搜索成员、部门"
  //             allowClear
  //             value={inputInfo}
  //             onChange={onSearch}
  //           />
  //           <Spin spinning={props.treeLoading || false}>
  //             {filteredData.length === 0 && !props.treeLoading ? (
  //               <NoData />
  //             ) : (
  //               <OrganizationTree
  //                 flattenTree={flattenTree}
  //                 treeData={filteredData}
  //                 onCheck={treeSelect}
  //                 checkedKeys={checkedOrgs}
  //                 expandKeys={expandKeys}
  //                 onlyUser={true}
  //                 mode="single"
  //               />
  //             )}
  //           </Spin>
  //         </div>
  //         <div className={styles.right}>
  //           {checkedOrgItems &&
  //             filterItems(checkedOrgs, checkedOrgItems).map(el =>
  //               el.visible ? <div key={el.key}>{el.title}</div> : null,
  //             )}
  //         </div>
  //       </div>
  //     </div>
  //   </Modal>
  // );
};

export default connect(({ loading }: ConnectState) => ({
  treeLoading: loading.effects['design/getOrgData']
}))(OrgToUserModal);
